<template>
  <table cellspacing="0">
    <tr
      :style="{
        ...topStyle,
      }"
    >
      <td v-show="multiple" width="100" align="center" class="top-column">
        <div class="checkbox-th">
          <div class="checkbox" @click="changeCheckAll">
            <img v-show="isCheckAll" :src="publicUrl(`/images/checkbox.png`)" />
          </div>
          <span class="text">全选</span>
        </div>
      </td>
      <td
        :width="item.width ? item.width : undefined"
        v-for="item in column"
        align="center"
        class="top-column"
      >
        <div v-show="item.headerSlotName">
          <slot :name="`header_${item.headerSlotName}`" :row="item"> </slot>
        </div>
        <span v-show="!item.headerSlotName" class="text">
          {{ item.title }}
        </span>
      </td>
    </tr>

    <tr v-for="(item, index) in factoryShow">
      <td :colspan="colspanNum">
        <table style="width: 100%">
          <tr>
            <td :colspan="colspanNum">
              <div
                :class="[
                  'factory',
                  props.tagShow ? `` : `factory-padding-bottom`,
                ]"
              >
                <div class="left">
                  <div
                    class="checkbox"
                    v-show="multiple"
                    @click="() => changeFactoryOrder(index)"
                  >
                    <img
                      v-show="item.checked"
                      :src="publicUrl(`/images/checkbox.png`)"
                    />
                  </div>

                  <span class="part-1">{{ item.factoryName }}</span>

                  <img
                    v-show="item.factoryCustomer.length > 0"
                    class="customer-icon"
                    :src="publicUrl(`/images/customer-orange.png`)"
                  />

                  <CustomerComponents
                    :title="`工厂客服`"
                    :customer="item.factoryCustomer"
                  />

                  <div class="part-4" v-if="showSel">
                    <Select
                      placeholder="优惠券"
                      :options="item.factoryCoupon"
                      :searchable="false"
                      :styleColor="`#C71D32`"
                      :optionColor="`#C71D32`"
                      :borderColor="`#C71D32`"
                      :valueColor="`#C71D32`"
                      :noneColor="`#C71D32`"
                      :searchColor="`#C71D32`"
                      label="coupon_name"
                      :reduce="(option:FactoryCoupon) => option.coupon_id"
                      :clearable="true"
                      v-model:value="item.couponValue"
                    />
                  </div>
                </div>

                <CustomerComponents
                  :title="`平台客服`"
                  :customer="platformCustomer"
                />
              </div>

              <div
                v-for="(items, key) in item.order"
                :class="['tb', props.tagShow ? 'tb-margin-top' : ``]"
              >
                <!-- 每个工厂每个不同类型的订单 -->

                <div
                  class="tb-title"
                  v-show="items && items.length > 0 && props.tagShow"
                >
                  {{ orderItemName(key) }}
                </div>

                <table
                  cellspacing="0"
                  class="tb-boder"
                  v-for="(orderItem, orderItemKey) in items"
                >
                  <tr class="order-item-tr">
                    <td v-show="multiple" width="100">
                      <div class="checkbox-th">
                        <div
                          class="checkbox"
                          @click="() => changeOrder(index, key, orderItemKey)"
                        >
                          <img
                            v-show="orderItem.checked"
                            :src="publicUrl(`/images/checkbox.png`)"
                          />
                        </div>
                      </div>
                    </td>

                    <td
                      class="orderItemtd"
                      :width="item.width"
                      v-for="item in column"
                      :align="item.tdAlign"
                    >
                      <!-- itemKey, orderType, orderItemKey -->
                      <div class="td-div" v-show="!item.slotName">
                        {{
                          item.dataKey
                            ? item.callback !== undefined
                              ? item.callback(orderItem[item.dataKey])
                              : orderItem[item.dataKey]
                            : ``
                        }}
                      </div>
                      <div class="td-div" v-show="item.slotName">
                        <slot
                          :name="item.slotName"
                          :row="orderItem"
                          :orderType="key"
                          :itemKey="index"
                          :orderItemKey="orderItemKey"
                        ></slot>
                      </div>
                    </td>
                  </tr>
                  <tr v-for="orderTrItem in props.addOrderTr">
                    <td :colspan="colspanNum">
                      <slot
                        :name="orderTrItem"
                        :row="orderItem"
                        :orderType="key"
                        :itemKey="index"
                        :orderItemKey="orderItemKey"
                      ></slot>
                    </td>
                  </tr>
                </table>
              </div>
            </td>
          </tr>

          <tr>
            <td :colspan="colspanNum">
              <slot
                name="factoryBottom"
                :row="item"
                :factoryReduces="factoryReduces(item)"
              >
              </slot>
            </td>
          </tr>
          <tr>
            <td :colspan="colspanNum">
              <slot name="factoryRemarks" :row="item"> </slot>
            </td>
          </tr>
        </table>
      </td>
    </tr>
    <div class="empty-data" v-show="factoryShow.length === 0">暂无数据</div>
  </table>
</template>
<script setup lang="ts" name="">
import { computed, ref } from "vue";
import {
  Column,
  Factory,
  OrderShow,
  Customer,
  FactoryOrder,
  FactoryCoupon,
  CartChecked,
  CartEcashChecked,
  CartReduce,
} from "./interface";
// import { toast } from "vue3-toastify";
import { publicUrl, twoFixed } from "@/utils/util";
import CustomerComponents from "@/components/Customer/index.vue";
// import vSelect from "vue-select";
import Select from "@/components/Select/index.vue";
// import "@/styles/VueSelect/vue-select.css";
// import "./select.css";

interface Prop {
  column?: Array<Column>;                      //购物车表格头部标题 /views/shopcart/index.vue 页面
  showSel?:boolean;                            //是否显示优惠券
  topCss?: { [key: string]: any };             //头部css
  factoryData?: Array<Factory>;                //工厂数据
  multiple?: boolean;                          //是否显示多选框
  tagShow?: boolean;                           //是否显示那个diy订单 现货 那个tag标签
  addOrderField?: { [key: string]: any };       //每张订单要追加的字段
  addFactoryField?: { [key: string]: any };     //每间工厂要追加的字段
  addOrderTr?: Array<string>; //插入订单Tr 插槽为
  addFactoryTr?: Array<string>; //插入工厂Tr 插槽为
  platformCustomer?: Array<Customer>; //平台客服
}

interface AddField {
  [key: string]: any;
}
interface AddOrderField extends OrderShow {
  [key: string]: any;
}

interface FactoryShow extends Factory<AddOrderField>, AddField {
  checked?: boolean;
  couponValue?: number | undefined;
  factoryCustomerIndex?: number | undefined;
}

interface OrderKeys {
  factoryIndex: number;
  key: keyof FactoryOrder;
  orderIndex: number;
}

const props = withDefaults(defineProps<Prop>(), {
  multiple: false,
  addOrderField: () => {
    return {};
  },
  tagShow: true,
  addOrderTr: () => [],
  column: () => [],
  addFactoryTr: () => [],
  factoryData: () => {
    return [];
  },
  showSel:true,
  platformCustomer: () => [],
});

const colspanNum = ref<number>(props.column.length + (props.multiple ? 1 : 0));

const initData = (data: Array<Factory>): Array<FactoryShow> => {
  return data.map((item: FactoryShow) => {
    if (props.multiple) item.checked = true;

    item.couponValue = undefined; //所选优惠卷

    item.factoryCustomerIndex = item.factoryCustomer.length > 0 ? 0 : undefined; //所选工厂客服

    item = Object.assign(item, props.addFactoryField);

    let key: keyof FactoryOrder<OrderShow>;

    for (key in item.order) {
      item.order[key] = item.order[key]?.map((items: OrderShow) => {
        items.checked = true;
        items.deleteLoading = false;
        items.price = Number(twoFixed(items.price));

        items = Object.assign(items, props.addOrderField);
        return items;
      });
    }

    return item;
  });
};

const factoryShow = ref<Array<FactoryShow>>(initData(props.factoryData));

const orderItemName = (key: keyof FactoryOrder): string => {
  switch (key) {
    case "diy":
      return "DIY定制款式";
    case "spot":
      return "现货商品";
    case "fabric":
    default:
      return "面料采购单";
  }
};

const getOrderChecked = (): OrderKeys[] => {
  const orderKeys: OrderKeys[] = [];
  for (let i = 0; i < factoryShow.value.length; i++) {
    let key: keyof FactoryOrder;
    for (key in factoryShow.value[i].order) {
      let factoryOrder = factoryShow.value[i].order[key] as OrderShow[];
      for (let j = 0; j < factoryOrder.length; j++) {
        if (factoryOrder[j].checked === true) {
          orderKeys.push({
            factoryIndex: i,
            key: key,
            orderIndex: j,
          });
        }
      }
    }
  }
  return orderKeys;
};

const topStyle = computed((): { [key: string]: string | undefined } => {
  return {
    ...props.topCss,
  };
});

const changeFactoryOrder = (index: number) => {
  factoryShow.value[index].checked = !factoryShow.value[index].checked;
  factoryShow.value[index] = setOrderChecked(
    factoryShow.value[index].checked as boolean,
    factoryShow.value[index]
  );
};

const changeOrder = (
  index: number,
  key: "diy" | "fabric" | "spot",
  orderItemKey: number
) => {
  (factoryShow.value[index].order[key] as any)[orderItemKey].checked = !(
    factoryShow.value[index].order[key] as any
  )[orderItemKey].checked; //反选
  factoryShow.value[index].checked = checkOrderFunc(
    factoryShow.value[index],
    true
  );
};

const changeCheckAll = () => {
  isCheckAll.value === true
    ? setAllFactoryChecked(false)
    : setAllFactoryChecked(true);
};

const setAllFactoryChecked = (checked: boolean) => {
  factoryShow.value = factoryShow.value.map((item: FactoryShow) => {
    item.checked = checked;
    item = setOrderChecked(checked, item);
    return item;
  });
};

const setOrderChecked = (checked: boolean, data: FactoryShow) => {
  let key: keyof FactoryOrder;
  for (key in data.order) {
    data.order[key] = data.order[key]?.map((items: OrderShow) => {
      items.checked = checked;
      return items;
    });
  }
  return data;
};

/**
 * @description:   订单出现某种选中状态直接返回true
 * @param {*} item 工厂数据
 * @param {*} checked   订单选中状态
 * @return {*}
 */
const checkOrderFunc = (item: FactoryShow, checked: boolean) => {
  let key: keyof FactoryOrder;
  for (key in item.order) {
    if (
      item.order[key]?.findIndex(
        (orderItem: OrderShow) => orderItem.checked === checked
      ) !== -1
    ) {
      return true;
    }
  }

  return false;
};

/**
 * @description:       检查工厂有没有订单
 * @param  {number}    工厂下标
 * @return {boolean}   true 为有单 false为无单
 */
const checkFactoryHaveOrder = (index: number): boolean => {
  let key: keyof FactoryOrder;
  for (key in factoryShow.value[index].order) {
    if (
      factoryShow.value[index].order[key] &&
      (factoryShow.value[index].order[key] as OrderShow[]).length > 0
    )
      return true;
  }
  return false;
};

const isCheckAll = computed((): boolean => {
  return (
    factoryShow.value.findIndex((item: FactoryShow) => {
      if (item.checked === false) return true;
      return checkOrderFunc(item, false);
    }) === -1
  );
});

const resetFactory = (index: number) => {
  factoryShow.value[index].checked = checkOrderFunc(
    factoryShow.value[index],
    true
  );
};

const cartChecked = computed((): CartChecked => {
  return factoryShow.value.reduce(
    (pre, curr: FactoryShow) => {
      // 计算每个厂的价钱
      const { discount, totalPrice, goods_num, lastPrice } =
        factoryReduces(curr);
      pre.goods_num += goods_num;
      pre.totalPrice += totalPrice;
      pre.discount += discount;
      pre.lastPrice += lastPrice;
      return pre;
    },
    { goods_num: 0, totalPrice: 0.0, discount: 0.0, lastPrice: 0.0 }
  );
});

const reduces = (item: OrderShow[]): CartReduce => {
  let pre: CartReduce = { goods_num: 0, totalPrice: 0.0 };
  for (let i = 0; i < item.length; i++) {
    if (item[i].checked) {
      pre.goods_num += item[i].total;
      pre.totalPrice += item[i].total * item[i].price;
    }
  }

  return pre;
};

const factoryReduces = (curr: FactoryShow): CartEcashChecked => {
  let pre = {
    goods_num: 0,
    totalPrice: 0.0,
    discount: 0,
    lastPrice: 0.0,
    eCash: 0.0,
  };

  /* 计算工厂每张单加钱 */
  let key: keyof FactoryOrder;
  for (key in curr.order) {
    const { goods_num, totalPrice } = reduces(curr.order[key] as OrderShow[]);
    pre.goods_num += goods_num;
    pre.totalPrice += totalPrice;
  }
  /**/

  /* 计算工厂优惠卷*/
  if (curr.couponValue !== undefined && curr.factoryCoupon.length > 0) {
    const coupon = curr.factoryCoupon.find(
      (item) => item.coupon_id === curr.couponValue
    );
    if (coupon) pre.discount += coupon.coupon_discount;
  }
  /**/

  // console.log(pre.discount );

  pre.lastPrice =
    pre.totalPrice - pre.discount > 0 ? pre.totalPrice - pre.discount : 0;

  if (curr.freight) pre.lastPrice += curr.freight; //运费
  if (curr.invoice && curr.tax) pre.lastPrice += curr.tax; //开发票打税

  /** 含有电子现金卷        */
  if (curr.eCash) {
    let eCash = curr.eCash;
    pre.eCash = eCash;
    /** 使用电子现金券        */
    if (curr.voucher) {
      if (pre.lastPrice >= curr.eCash) {
        //     //最后价钱大于现金使用卷
        pre.lastPrice -= pre.eCash; //最后价钱 - 电子卷
        pre.eCash = 0; //电子卷用完了归0
      } else {
        pre.eCash -= pre.lastPrice; //现金使用卷还有剩余
        pre.lastPrice = 0; // 抵消掉了价格
      }
    }
    /**/
  }
  /**/
  return pre;
};

const delOrder = (
  itemKey: number,
  orderType: "diy" | "spot" | "fabric",
  orderItemKey: number
) => {
  factoryShow.value[itemKey].order[orderType]?.splice(orderItemKey, 1);
};

const batchDelOrder = (checkedArr?: OrderKeys[]) => {
  let restKeysArr: {
    [key: number]: {
      //工厂下标
      diy: number;
      spot: number;
      fabric: number;
    };
  } = {};
  if (!checkedArr) checkedArr = getOrderChecked();
  for (let i = 0; i < checkedArr.length; i++) {
    if (!restKeysArr.hasOwnProperty(checkedArr[i].factoryIndex)) {
      restKeysArr[checkedArr[i].factoryIndex] = {
        //工厂下标 不同的订单
        diy: -1,
        spot: -1,
        fabric: -1,
      };
    }
    restKeysArr[checkedArr[i].factoryIndex][checkedArr[i].key]++; //防止splice后排序改变错乱
    delOrder(
      checkedArr[i].factoryIndex,
      checkedArr[i].key,
      checkedArr[i].orderIndex -
        restKeysArr[checkedArr[i].factoryIndex][checkedArr[i].key]
    );
  }
  let indexs = -1;
  for (let key in restKeysArr) {
    indexs++;
    let bool = checkFactoryHaveOrder(Number(key) - indexs);
    bool
      ? resetFactory(Number(key) - indexs)
      : delFactory(Number(key) - indexs); //有单的情况下重置工厂勾选情况 没有则删除工厂
  }
};

const delFactory = (itemKey: number) => {
  factoryShow.value.splice(itemKey, 1);
};

defineExpose({
  cartChecked,
  resetFactory,
  delFactory,
  delOrder,
  isCheckAll,
  factoryReduces,
  batchDelOrder,
  changeCheckAll,
  getOrderChecked,
  checkFactoryHaveOrder,
});
</script>
<style scoped lang="scss">
@import "./index.scss";
</style>
